package spring.cloud.tasks.common.node;

import com.alibaba.fastjson2.JSON;
import org.apache.curator.framework.CuratorFramework;
import spring.cloud.tasks.common.BatchTaskInstanceInfo;
import spring.cloud.tasks.common.BatchTaskReStartInfo;
import spring.cloud.tasks.common.task.TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex;
import spring.cloud.tasks.common.task.TaskItemExecuteRenewalInfo;
import spring.cloud.tasks.common.zookeeper.ZooKeeper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 块级节点 不是阻塞的意思哈
 */
public class BlockNodePaths {
    public static final String ENABLE_TASKS_NODE_PATH = "/enabled_task";
    //
    public static final String TASK_PRE_ASSIGN_TIME_POINT_NODE_PATH = "task_pre_assign_time_point";
    //
    public static final String EXECUTOR_TASKS_NODE_PATH = "/executor_tasks";
    //
    public static final String ONLINE_EXECUTOR_TASK_ITEM_ASSIGNS_NODE_PATH = "/online_executor_task_item_assigns";

    public static String getEnableTaskNodePath(String taskId) {
        return String.format(ENABLE_TASKS_NODE_PATH + "/%s", taskId);
    }

    public static String getExecutorTaskNode(String executorId, String taskId) {
        return EXECUTOR_TASKS_NODE_PATH + "/" + executorId + "/" + taskId;
    }

    public static String getExecutorTasksNodePath(String executorId) {
        return EXECUTOR_TASKS_NODE_PATH + "/" + executorId;
    }

    public static String getOnlineExecutorTaskItemAssignsNodePath(String element) {
        return ONLINE_EXECUTOR_TASK_ITEM_ASSIGNS_NODE_PATH + "/" + element;
    }

    //
    public static final String TASK_ITEM_NODES_PATH = "/task_item_nodes";

    public static String getTaskItemNodesTasksNodePath() {
        return TASK_ITEM_NODES_PATH;
    }

    public static String getTaskItemNodesTaskInstancesNodePath(String taskId) {
        return TASK_ITEM_NODES_PATH + "/" + taskId;
    }

    public static String getTaskItemNodesTaskRoundIdsNodePath(String taskId, String taskInstanceId) {
        return TASK_ITEM_NODES_PATH + "/" + taskId + "/" + taskInstanceId;
    }

    public static String getTaskItemNodesTaskItemsNodePath(String taskId, String taskInstanceId, String taskRoundId) {
        return TASK_ITEM_NODES_PATH + "/" + taskId + "/" + taskInstanceId + "/" + taskRoundId;
    }

    public static String getTaskItemNodesTaskItemNodePath(String taskId, String taskInstanceId, String taskRoundId, String taskItemIndex) {
        return TASK_ITEM_NODES_PATH + "/" + taskId + "/" + taskInstanceId + "/" + taskRoundId + "/" + taskItemIndex;
    }

    public static List<String> getTaskItemIndexPathListList(CuratorFramework curatorFramework) throws Exception {
        String taskItemNodesTasksNodePath = getTaskItemNodesTasksNodePath();
        List<String> oldTaskItemIndexPathList = new ArrayList<String>();
        List<String> oldTaskIdList = curatorFramework.getChildren().forPath(taskItemNodesTasksNodePath);
        if (oldTaskIdList != null && !oldTaskIdList.isEmpty()) {
            for (String taskId : oldTaskIdList) {
                oldTaskItemIndexPathList.addAll(getTaskItemIndexPathListList(curatorFramework, taskId));
            }
        }
        return oldTaskItemIndexPathList;
    }

    public static List<String> getTaskItemIndexPathListList(CuratorFramework curatorFramework, String taskId) throws Exception {
        List<String> oldTaskItemIndexPathList = new ArrayList<String>();
        List<String> taskInstanceIdList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskInstancesNodePath(taskId));
        if (taskInstanceIdList != null) {
            for (String taskInstanceId : taskInstanceIdList) {
                List<String> taskRoundIdList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskRoundIdsNodePath(taskId, taskInstanceId));
                if (taskRoundIdList != null) {
                    for (String taskRoundId : taskRoundIdList) {
                        List<String> taskItemIndexList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskItemsNodePath(taskId, taskInstanceId, taskRoundId));
                        if (taskItemIndexList != null) {
                            for (String taskItemIndex : taskItemIndexList) {
                                String taskItemIndexPath = BlockNodePaths.getTaskItemNodesTaskItemNodePath(taskId, taskInstanceId, taskRoundId, taskItemIndex);
                                oldTaskItemIndexPathList.add(taskItemIndexPath);
                            }
                        }
                    }
                }
            }
        }
        return oldTaskItemIndexPathList;
    }

    public static List<TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex> getTaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndexList(CuratorFramework curatorFramework, String taskId) throws Exception {
        List<TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex> list = new ArrayList<>();
        List<String> taskInstanceIdList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskInstancesNodePath(taskId));
        if (taskInstanceIdList != null) {
            for (String taskInstanceId : taskInstanceIdList) {
                List<String> taskRoundIdList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskRoundIdsNodePath(taskId, taskInstanceId));
                if (taskRoundIdList != null) {
                    for (String taskRoundId : taskRoundIdList) {
                        List<String> taskItemIndexList = curatorFramework.getChildren().forPath(BlockNodePaths.getTaskItemNodesTaskItemsNodePath(taskId, taskInstanceId, taskRoundId));
                        if (taskItemIndexList != null) {
                            for (String taskItemIndex : taskItemIndexList) {
                                //String taskItemIndexPath = BlockNodePaths.getTaskItemNodesTaskItemNodePath(taskId, taskInstanceId, taskRoundId, taskItemIndex);
                                TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex = new TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex();
                                taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.setTaskId(taskId);
                                taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.setTaskInstanceId(taskInstanceId);
                                taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.setTaskTurnId(taskRoundId);
                                taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.setTaskItemIndex(taskItemIndex);
                                list.add(taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex);
                            }
                        }
                    }
                }
            }
        }
        return list;
    }


    public static String getTaskRenewalDimensionInstancesNodePath(final String taskId) {
        return "/renewal/" + taskId;
    }

    public static String getTaskRenewalDimensionInstanceTurnsNodePath(final String taskId, final String taskInstanceId) {
        return "/renewal/" + taskId + "/" + taskInstanceId;
    }

    public static String getTaskRenewalDimensionInstanceTurnItemsNodePath(final String taskId, final String taskInstanceId, final String taskTurnId) {
        return "/renewal/" + taskId + "/" + taskInstanceId + "/" + taskTurnId;
    }

    public static String getTaskRenewalDimensionInstanceTurnItemsNodePath(final String taskId, final String taskInstanceId, final String taskTurnId, final String taskItemIndex) {
        return "/renewal/" + taskId + "/" + taskInstanceId + "/" + taskTurnId + "/" + taskItemIndex;
    }

    public static List<TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex> getTaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndexList(ZooKeeper zooKeeper, String taskId) {
        List<TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex> list = new ArrayList<TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex>();
        List<String> taskInstanceIdList = zooKeeper.getChildren(getTaskRenewalDimensionInstancesNodePath(taskId));
        for (String taskInstanceId : taskInstanceIdList) {
            List<String> taskTurnList = zooKeeper.getChildren(getTaskRenewalDimensionInstanceTurnsNodePath(taskId, taskInstanceId));
            if (taskTurnList != null) {
                for (String taskTurn : taskTurnList) {
                    List<String> taskItemIndexList = zooKeeper.getChildren(getTaskRenewalDimensionInstanceTurnItemsNodePath(taskId, taskInstanceId, taskTurn));
                    if (taskItemIndexList != null) {
                        for (String taskItemIndex : taskItemIndexList) {
                            TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex taskInstanceAndTaskItem = new TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex();
                            taskInstanceAndTaskItem.setTaskId(taskId);
                            taskInstanceAndTaskItem.setTaskInstanceId(taskInstanceId);
                            taskInstanceAndTaskItem.setTaskTurnId(taskTurn);
                            taskInstanceAndTaskItem.setTaskItemIndex(taskItemIndex);
                            list.add(taskInstanceAndTaskItem);
                        }

                    }
                }

            }
        }
        return list;
    }

    public static TaskItemExecuteRenewalInfo getTaskItemExecuteRenewalInfo(ZooKeeper zooKeeper, TaskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex) {
        String nodePath = getTaskRenewalDimensionInstanceTurnItemsNodePath(taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.getTaskId(), taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.getTaskInstanceId(), taskIdAndTaskInstanceIdAndTaskTurnIdAndTaskItemIndex.getTaskItemIndex());
        if (!zooKeeper.checkExists(nodePath)) {
            return null;
        } else {
            String data = zooKeeper.getData(nodePath);
            TaskItemExecuteRenewalInfo taskItemExecuteRenewalInfo = JSON.parseObject(data, TaskItemExecuteRenewalInfo.class);
            return taskItemExecuteRenewalInfo;
        }
    }

    public static TaskItemExecuteRenewalInfo getTaskItemExecuteRenewalInfo(ZooKeeper zooKeeper, String taskItemExecuteRenewalInfoNodePath) {
        if (!zooKeeper.checkExists(taskItemExecuteRenewalInfoNodePath)) {
            return null;
        } else {
            String data = zooKeeper.getData(taskItemExecuteRenewalInfoNodePath);
            TaskItemExecuteRenewalInfo taskItemExecuteRenewalInfo = JSON.parseObject(data, TaskItemExecuteRenewalInfo.class);
            return taskItemExecuteRenewalInfo;
        }
    }

    //批量处理 包括在重启和正常运行
    public static final String BATCH_TASKS_RESTART_NODE_PATH = "/batch_task/restart";
    public static final String BATCH_TASKS_LIST_NODE_PATH = "/batch_task/list";

    public static String getBatchTasksRestartNodePath(String node) throws Exception {
        return BATCH_TASKS_RESTART_NODE_PATH + "/" + node;
    }

    public static String getBatchTasksInfoNodePath(String node) throws Exception {
        return BATCH_TASKS_RESTART_NODE_PATH + "/" + node;
    }

    public static ConcurrentHashMap<String, List<BatchTaskReStartInfo>> getBatchTaskReStartInfoListMap(CuratorFramework curatorFramework) throws Exception {
        ConcurrentHashMap<String, List<BatchTaskReStartInfo>> taskIdToBatchTaskReStartInfoListMap = new ConcurrentHashMap<String, List<BatchTaskReStartInfo>>();
        if (curatorFramework.checkExists().forPath(BATCH_TASKS_RESTART_NODE_PATH) == null) {
            return taskIdToBatchTaskReStartInfoListMap;
        } else {
            List<String> taskRoundIdList = curatorFramework.getChildren().forPath(BATCH_TASKS_RESTART_NODE_PATH);
            if (taskRoundIdList == null) {
                return taskIdToBatchTaskReStartInfoListMap;
            }
            for (String taskRoundId : taskRoundIdList) {
                String data = String.valueOf(curatorFramework.getData().forPath(getBatchTasksRestartNodePath(taskRoundId)));
                BatchTaskReStartInfo batchTaskReStartInfo = JSON.parseObject(data, BatchTaskReStartInfo.class);
                taskIdToBatchTaskReStartInfoListMap.put(batchTaskReStartInfo.getTaskId(), new ArrayList<>());
                taskIdToBatchTaskReStartInfoListMap.get(batchTaskReStartInfo.getTaskId()).add(batchTaskReStartInfo);
            }
        }
        return taskIdToBatchTaskReStartInfoListMap;
    }

    public static ConcurrentHashMap<String, List<BatchTaskInstanceInfo>> getBatchTaskInstanceInfoListMap(CuratorFramework curatorFramework) throws Exception {
        ConcurrentHashMap<String, List<BatchTaskInstanceInfo>> taskIdToBatchTaskInstanceInfoListMap = new ConcurrentHashMap<String, List<BatchTaskInstanceInfo>>();
        if (curatorFramework.checkExists().forPath(BATCH_TASKS_LIST_NODE_PATH) == null) {
            return taskIdToBatchTaskInstanceInfoListMap;
        } else {
            List<String> taskRoundIdList = curatorFramework.getChildren().forPath(BATCH_TASKS_LIST_NODE_PATH);
            if (taskRoundIdList == null) {
                return taskIdToBatchTaskInstanceInfoListMap;
            }
            for (String taskRoundId : taskRoundIdList) {//string=taskRoundId 能够快速进行更新
                String data = String.valueOf(curatorFramework.getData().forPath(getBatchTasksRestartNodePath(taskRoundId)));
                BatchTaskInstanceInfo batchTaskInstanceInfo = JSON.parseObject(data, BatchTaskInstanceInfo.class);
                taskIdToBatchTaskInstanceInfoListMap.put(batchTaskInstanceInfo.getTaskId(), new ArrayList<>());
                taskIdToBatchTaskInstanceInfoListMap.get(batchTaskInstanceInfo.getTaskId()).add(batchTaskInstanceInfo);
            }
        }
        return taskIdToBatchTaskInstanceInfoListMap;
    }
}
